{
 "metadata": {
  "name": "Distributed Aggregate and Join"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%pylab inline"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "\n",
        "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.kernel.zmq.pylab.backend_inline].\n",
        "For more information, type 'help(pylab)'.\n"
       ]
      }
     ],
     "prompt_number": 42
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import numpy as np\n",
      "import pandas as pd\n",
      "import pylab as pl"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 43
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from sklearn.utils import murmurhash3_32"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 24
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "n_groups = 100\n",
      "n_samples = 100000\n",
      "\n",
      "group_id = np.asarray(np.random.randint(n_groups, size=n_samples), dtype=np.int32)\n",
      "data = np.random.normal(size=n_samples)\n",
      "\n",
      "df = pd.DataFrame({'group_id': group_id, 'data': data})"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 25
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%time grouped = df.groupby('group_id')\n",
      "%time aggregate = grouped.sum()\n",
      "\n",
      "aggregate[:10]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "CPU times: user 253 \u00b5s, sys: 16 \u00b5s, total: 269 \u00b5s\n",
        "Wall time: 271 \u00b5s\n",
        "CPU times: user 4.9 ms, sys: 474 \u00b5s, total: 5.37 ms\n",
        "Wall time: 4.86 ms\n"
       ]
      },
      {
       "html": [
        "<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>data</th>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>group_id</th>\n",
        "      <th></th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>  4.974845</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>-50.376857</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>  5.168091</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>3</th>\n",
        "      <td>  6.355739</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>4</th>\n",
        "      <td> 22.481601</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>5</th>\n",
        "      <td> -0.748311</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>6</th>\n",
        "      <td>-73.982681</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>7</th>\n",
        "      <td>  4.263864</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>8</th>\n",
        "      <td> 43.841003</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>9</th>\n",
        "      <td> 14.636269</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 105,
       "text": [
        "               data\n",
        "group_id           \n",
        "0          4.974845\n",
        "1        -50.376857\n",
        "2          5.168091\n",
        "3          6.355739\n",
        "4         22.481601\n",
        "5         -0.748311\n",
        "6        -73.982681\n",
        "7          4.263864\n",
        "8         43.841003\n",
        "9         14.636269"
       ]
      }
     ],
     "prompt_number": 105
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "murmurhash3_32(df.group_id, 0) % 4"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 27,
       "text": [
        "array([1, 2, 3, ..., 0, 1, 2], dtype=int32)"
       ]
      }
     ],
     "prompt_number": 27
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from IPython.parallel import Client\n",
      "client = Client()\n",
      "len(client)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 28,
       "text": [
        "4"
       ]
      }
     ],
     "prompt_number": 28
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from sklearn.utils import gen_even_slices\n",
      "\n",
      "list(gen_even_slices(100, 4))[2]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 29,
       "text": [
        "slice(50, 75, None)"
       ]
      }
     ],
     "prompt_number": 29
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "# Python sorting timings"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import numpy as np"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 30
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "n_samples = int(1e7)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 58
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "a = np.random.normal(size=n_samples)\n",
      "%time a.sort()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "CPU times: user 1.02 s, sys: 1.87 ms, total: 1.02 s\n",
        "Wall time: 1.02 s\n"
       ]
      }
     ],
     "prompt_number": 59
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "_ = pl.plot(a)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\nAAAAAElFTkSuQmCC\n",
       "text": [
        "<matplotlib.figure.Figure at 0x12b806490>"
       ]
      }
     ],
     "prompt_number": 60
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "b = np.random.normal(size=n_samples)\n",
      "%time b.sort()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "CPU times: user 1e+03 ms, sys: 1.43 ms, total: 1 s\n",
        "Wall time: 1 s\n"
       ]
      }
     ],
     "prompt_number": 61
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "c = np.r_[a[:n_samples / 2], b[:n_samples / 2]]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 98
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "_ = pl.plot(c)\n",
      "c.shape"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 99,
       "text": [
        "(10000000,)"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "iVBORw0KGgoAAAANSUhEUgAAAXUAAAEICAYAAACgQWTXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHW9JREFUeJzt3XtYVHX+B/D3KFhaWl7KVcA0sdBQxHC9lDTmjnlJ7anc\npO2mPupm2RbbZub2Cysp63E3V8tsvW14Y9UMW5UN1EFTEK+IZkiiCRauF8iIDNDz++OzgC2Kw5zD\nOWe+8349zzwOMDPfT+c55913vud7vsehaZoGIiJSQgOrCyAiIuMw1ImIFMJQJyJSCEOdiEghDHUi\nIoUw1ImIFKI71MeMGYPWrVuja9euRtRDREQ66A710aNHIzk52YhaiIhIJ92h3q9fPzRv3tyIWoiI\nSCeOqRMRKSSgvhtwOBz13QQRkZK8WcXFlJ66pml8aBpee+01y2uwy4PbgtuC26L2h7c4/EJEpBDd\noR4TE4O+ffvi8OHDCAkJwaJFi4yoi4iIvKB7TH358uVG1OEXnE6n1SXYBrdFNW6LatwW+jk0PYM3\nnjTgcOgaHyIi8kfeZifH1ImIFMJQJyJSCEOdiEghDHUiIoUw1ImIFMJQJyJSCEOdiEghDHUiIoUw\n1ImIFMJQJyJSCEOdiEghDHUiIoUw1ImIFMJQJyJSCEOdiEghDHUiIoUw1ImIFMJQJyJSCEOdiEgh\nDHUiIoUw1ImIFMJQJyJSiO5QT05ORlhYGDp16oQZM2YYURMREXnJoWma5u2bL1y4gNtvvx2pqakI\nCgpCz549sXz5cnTu3Lm6AYcDOpogIvJL3manrp56ZmYmQkND0b59ewQGBmLUqFFISkrS85FEpmFf\ng+zq4kXv3xugp+ETJ04gJCSk6ufg4GDs2LGjxuvi4uKqnjudTjidTj3NEnmluBjYtg3YskUeGRnA\nqVNAq1ZWV0b+rrwcmD/fjTVr3Dh+HDh+3PvP0hXqDofDo9ddGupEZvn2W2Dr1upHXh7w618D/foB\n8fHAyJFAaanVVZI/Ki0FduyQ/XLLFnl+661O9OvnxNixso8GBU3z6rN1hXpQUBDy8/Orfs7Pz0dw\ncLCejyTyiqZJaFceJFu2AGfPAnffDURHA48/DvToAQQGVr+nSRPr6iX/UlQk3xIrOxhZWUC3brJv\nPv88cNddQPPmxrSlK9SjoqKQm5uLY8eOoW3btkhMTMTy5cuNqYyoFhcvAl9+WR3gW7fK76OjpZcT\nGwt06QI04KRdssB331UH+JYt0uHo1Uv2zTfflOfXXVc/besK9YCAAMyZMwf33XcfLly4gLFjx/5i\n5guRUcrLgb17qwP8iy+AFi3kIBk0CJg+Hbj1VsDDEUEiw1R+S7y0g1FUJL3vfv2Ajz6q+S2xPuma\n0uhRA5zSSF746ScgM7P6QNmxA2jfXnrilb3xNm30tdGunfzPoV07Q0omP6FpwKFD1ftmWpr8/tJ9\n04hvid5mJ0OdbKGkBEhPlwMkLU165XfcIQdIdLT0elq2NLZNhjp54sIFIDtb9svKIG/aVPbLe+6R\nf+vjWyJDnXxKcbEEamVP5+BBIDIScDrlIOnTB7j++vqtgaFOl1NRAezZUx3iX3wB/OpX1T3x6Gjg\nkpnc9cbb7NQ1pk7kqbNnZawxLQ1wu4HcXJleeM89wIwZcuKocWOrqyR/VFYG7Nol+2VamnxjrBzq\ne/JJYP58oHVrq6v0HEOd6kVRkfRy3G55fP219L6dTmD2bKBnT6BRI4uLJL90aYi73RLioaGybz79\nNLBsmfFDfWZiqJMhioulJ755c3VPvDLE338fiIpiiJM1ysslxCv3zYwMoGNHoH9/4JlngMRE4+aI\n2wFDnbzyww/VIb5pE3D4MNC7t4T4nDkMcbLOhQsyJr5pk+yf27fLiUxVQ/x/MdTJI6WlcnBs2iSP\nAwdkCKV/f2DWLBkfZ4iTFTRN9sdNm4CNG6WzERQE3HsvMGECsHSpbw+n1BVDnS6rogLYuRNISZGD\nZdcuICJCDpT4eKBvX+Daa62ukvzV0aMS4Bs3yv55/fXAgAHAo48Cf/+7b53YNBpDnQBIb+fwYQnx\n1FQZe2zfHvjNb4CXXpL54k2bWl0l+avTp6t74ikp8s1xwADA5QLefhu45RarK7QPhrof+89/qg+S\n1FQJdpcLeOQRubT55putrpD81U8/yfzwyn3zyBGZYjhgADBpklyYxiUhLo+h7kdKS2W8MTVVDpZj\nx2SeuMsFTJ4M3HYbDxSyhqbJVZuffy6P9HRZxdDlAv72N7mOway1U3wdQ11hlSeQkpOBf/9bpnJ1\n7y4HygcfyMnNAO4BZJEzZyTAk5Pl3+uuAwYOBCZOBFauBG64weoKfRMPacUUFUkvvDLIr7lGVjGc\nNAn45BOgWTOrKyR/dfGiTDXcsEEeBw/KN8VBg4D/+z+ZO076MdR9XOXX1nXrgPXrZfH9u+8GBg8G\npkyRK+U4pEJWOXtWeuEbNkhHo0ULYMgQ4PXX5eT7NddYXaF6GOo+qLxcLsFfuxZISpIlPu+/H5g6\nVXo+XEOFrKJp0rH4178kyLOz5YK0wYOBadNkRhXVL4a6jzh3Tno6SUlysISGAiNGyMHDmQBkpfPn\nZbrhZ5/Jo3FjYOhQIC5OeuO8nsFcDHUbKyio7o2np8uwyogRwLvvAm3bWl0d+bNTp6RD8dlnMi02\nIgIYNkxmVoWFWV2df2Oo24imAfv3S4gnJcmUw6FDgXHjgFWrePEPWevIEeDTT+Wxf7/MonrgAbmm\noVUrq6ujSgx1i11ufHzECGDmTOmZc8ohWUXTZIbK6tUyc+rkSWD4cOCVV2S5CJ7ktCdGhgVKS2Wm\nypo1HB8ne6k80blypXw7PH8eeOghWT65Tx+gYUOrK6SrYaib5Kef5ERnYqL827OnHCwcHyc7OHRI\nbg6RmCiLuT38MJCQIPspOxm+haFejyoq5CTSsmUyvNK9u6yrMns2cNNNVldH/q6wEFixAliyBPj2\nWyAmRvbVO+9kkPsyhrrBNA3YsUPWcP7nP2Ve7qOPykpybdpYXR35u5ISOdG5ZInspyNGyL7Zvz+H\nVlTRQM+bV65ciTvuuAMNGzbEnj17jKrJJx0/Drz5piyK9dRTssLhtm1y4PzhDwx0sk5FhQz5PfYY\nEBwsvfOnngJOnAAWL5bllRno6tDVU+/atSvWrFmDCRMmGFWPT/nxR5kV8I9/AHv3ytDK0qUchyTr\naZrc2GTJEhknb99eQv0vf+GSyqrTFephfniVQeXwyvz5MtWrb19g/HiZ6sUr58hqJ09K73vRIumh\nP/aYLLfcqZPVlZFZTBlTj4uLq3rudDrhdDrNaNZQ587JbIAPP5RpXmPHyhxezlwhq2manJD/8EP5\n98EHgYULZQoivzH6DrfbDbfbrftzHJqmabW9wOVyobCwsMbv4+PjMWzYMABA//79MXPmTPTo0aNm\nAw4HrtKErR04IGuPr1ghY4+//72cVOLB4vvatZO767RrZ3Ul3vnpJxnue+89+fmZZ4Df/Y7LK6vC\n2+y8ak89JSXFq4J8WVmZXBj0/vtyafT48RLu7JWTHXz7rXQ0PvpI7gg0a5Zc4cmOBgEGDr/4cm+8\n0pkz8hX2/fdlUaLnnpMpX7yNFtnBrl3SK1+/XnrkX3whs62ILqVrSuOaNWsQEhKCjIwMDB06FIMH\nDzaqLlPl5cmdgTp1Ar7+Wu4YtGmTXFXHQCcrVVTI5fp33y37Y2Sk7K+zZzPQ6fKuOqauuwEbj6ln\nZ8uFF//+t6yEOGkSh1j8iZ3H1L//Hvj73yW827UDnn9evjVygTf/4W126uqp+6rdu2XJ0IEDZR3o\nvDzgrbcY6GS94mK5uUTHjnI/z9WrZUriQw8x0MkzfhXqeXlygdDw4XJiKS8PeOklzhYg6507J/ft\nDA0FvvkGyMiQdViioqyujHyNX4T62bNAbCzw618DXbsCublyEpT38iSrnT8P/PWvcj4nN1fCfNEi\nCXcibygd6j//LDebCAuTOb0HDwJ//jPQpInVlZG/u3hR5piHhQGbN8tFQwkJDHPST8lROk2TFRKn\nTAHCw4G0NKBzZ6urIhKZmcCzz8q88oQEuTkzkVGUC/Vt24A//lGmgi1cCPjgigSkqB9/BF59VcbK\n33lH1mVpoPR3ZbKCMrtUcbGsx/LII9ILysxkoJN9pKbK+ZxTp+Tq5CeeYKBT/VCip56aCowZA9x/\nv9yWq2lTqysiEkVFwIsvyj764YeAj16fRz7Ep/sKpaUyi2X0aFkK94MPGOhkH598Iud0GjeW3jkD\nnczgsz31zEz5ChsVBezfDzRvbnVFROL0aVnN88ABuUHF3XdbXRH5E5/rqV+4IBdpDB8OvPGG3NmF\ngU52kZ4O9Oghdxrat4+BTubzqZ56UZHc8fz8ebl9HO/7SXaycCHw8svAggXAf281QGQ6n+mp5+TI\nFaFdushJJwY62UVFBfDCC7I43NatDHSylk/01LdulWVH4+Nl2iKRXXz/PfDb38rzHTs4FEjWs31P\n/dNP5Z6LS5Yw0MleCguB6GhZt2XdOgY62YOtQ33JEuDpp4ENGwCXy+pqiKodPy6X948cKWuec1lc\nsgvb7opLlgCTJ8tCR126WF0NUbX8fLn5+LPPylg6kZ3YMtRXrZJ1zlNTGehkL//5DzBgADBxIgOd\n7Ml2oZ6WJgfM558z0MleSkuBoUOBUaNk0TgiO7LVmPrhwzKTYMUKoHt3q6shqqZpsr5QWBgwbZrV\n1RBdmW166j/8IPcNfeMNudUckZ3MmCG3P0xLk3XQiezKFqGuacCECUDfvsD48VZXQ/RLqanA3/4m\n6w3xFohkd7YI9Y8/lkW5du60uhKiXzp9GnjySblDUXCw1dUQXZ2uMfU//elP6Ny5MyIiIvDggw/i\n+++/r/Nn5OfLetPLlrEXRPbz7LNyYnTAAKsrIfKMrlAfOHAgDh48iKysLNx2221466236vR+TZOZ\nLpMmAd266amEyHjr1gG7dwNvvml1JUSe0xXqLpcLDf57T65evXqhoKCgTu//7DPg669lZTsiO/n5\nZ+lsvP8+v0GSbzFsTH3hwoWIiYm57N/i4uKqnjudTjidTpSXy7DL7NlAo0ZGVUFkjDlz5J6iAwda\nXQn5C7fbDbfbrftzHJqmabW9wOVyobCwsMbv4+PjMey/a4xOnz4de/bswerVq2s24HDgck189BGw\nciWQkuJt6UT6tGsHfPGF/HupoiLgtttkddCwMGtqI7pSdl7NVXvqKVdJ3cWLF2P9+vXYuHGjx42W\nlQHTp8utvojs5r335M5aDHTyRbqGX5KTk/Huu+8iLS0N1157rcfvS0wEQkOB3r31tE5kvJISuYH5\n9u1WV0LkHV0nSidNmoSSkhK4XC5ERkZi4sSJV32PpklPKDZWT8tE9WPxYuCee2SNdCJfpKunnpub\nW+f3ZGYCxcXA4MF6WiYynqYBc+fKjBciX2X6gl5LlgCjRwMNbLWUGJFc0VxWJj11Il9l6jIBmgYk\nJcmdjIjsJiEBePxxLthFvs3UUM/KkjnpXCed7ObiRbk5y5YtVldCpI+pgyBJScCIEewJkf3s3Am0\nbMkTpOT7LAl1Irv517/krkZEvs60UD9+XB59+5rVIpHnUlKA++6zugoi/UwL9cqeUIAtVnAnqvbD\nD8CBA0CfPlZXQqSfaaGelsbb1JE9ZWQAPXpwNUZSg2mhvmMHe0JkT7t2AT17Wl0FkTFMCfXTp+Uq\nUs4sIDvatw+IjLS6CiJjmBLqWVlARASnMpI97d3LUCd1mBLq2dlAeLgZLRHVTUkJUFAA3H671ZUQ\nGcOUUD90iFeRkj199ZXcEIOzskgVpoT64cNy4BDZTW4uz/WQWkwJ9SNH5KYYRHaTl8d9k9RiSqgX\nFgLBwWa0RFQ3BQXcN0ktpoR669ZAYKAZLRHVzYkTQFCQ1VUQGceUUOdBQ3b17bdA27ZWV0FkHFNC\nvU0bM1ohqrtTp9jpILWYEuo332xGK0R1U1Eh/7ZubW0dREYyJdRbtTKjFaK6KSqSfzlHnVRiSqi3\nbGlGK0R1c/48A53UY0qo33CDGa0Q1V2zZlZXQGQsr0P91VdfRUREBLp3744BAwYgPz//iq9lqJNd\ncd8k1Xgd6i+99BKysrKwb98+PPDAA5g2bdoVX8sDh+yK+yapxutQb9q0adXzkpIStKrlbCgPHLIr\n7pukGl2niaZOnYqEhAQ0adIEGRkZV3zdxx/HYf16ee50OuF0OvU0S2QYhjrZhdvthtvt1v05Dk3T\ntCv90eVyobCwsMbv4+PjMWzYsKqf3377beTk5GDRokU1G3A4cPy4hpAQ3bUSGcrhAB57DEhIsLoS\nopocDgdqiecrqrWnnpKS4tGHPProoxgyZMgV/96kSd2KIjIL901Sjddj6rm5uVXPk5KSEFnL/cCu\nvdbbVojqV6NGVldAZCyvx9SnTJmCnJwcNGzYEB07dsTcuXOv+NprrvG2FaL6xVAn1Xgd6qtWrfL4\ntQ0betsKUf1iqJNqTLmi1OEwoxWiumOok2pMCXUiu2Kok2oY6uTXGOqkGoY6+TWGOqmGoU5+jTOz\nSDUMdfJr7KmTahjq5NcY6qQahjr5Nd75iFTDUCe/xmsoSDUMdSIihTDUya+xp06qYagTESmEoU5+\njT11Ug1DnYhIIQx18mvsqZNqGOpERAphqJNfY0+dVMNQJyJSCEOdiEghDHXyaxx+IdUw1ImIFMJQ\nJ7/GnjqphqFORKQQ3aE+c+ZMNGjQAGfPnjWiHiJTsadOqtEV6vn5+UhJScEtt9xiVD1ERKSDrlCP\njY3FO++8Y1QtRKZjT51U4/XNvJKSkhAcHIxu3bpd9bVxcXFVz51OJ5xOp7fNEhEpye12w+126/4c\nh6Zp2pX+6HK5UFhYWOP306dPR3x8PD7//HM0a9YMHTp0wK5du9CyZcuaDTgcqKUJIss4HEBSEjB8\nuNWVENXkbXbW2lNPSUm57O8PHDiAo0ePIiIiAgBQUFCAO++8E5mZmbj55pvrXAQRERnDq+GX8PBw\nnDx5surnDh06YPfu3WjRooVhhRGZgWPqpBpD5qk7eGQQEdmC1ydKL5WXl2fExxCZjv0RUg2vKCUi\nUghDnYhIIQx18mscfiHVMNSJiBTCUCe/xp46qYahTkSkEIY6+TX21Ek1DHUiIoUw1MmvsadOqmGo\nExEphKFOfo09dVINQ52ISCEMdfJr7KmTahjqREQKYaiTX2NPnVTDUCciUghDnYhIIQx18mscfiHV\nMNSJiBTCUCe/xp46qYahTkSkEIY6+TX21Ek1DHUiIoV4HepxcXEIDg5GZGQkIiMjkZycbGRdRKZg\nT51UE+DtGx0OB2JjYxEbG2tkPUREpIOu4RdN04yqg8gS7KmTarzuqQPA7Nmz8fHHHyMqKgozZ87E\njTfeeNnXxcXFVT13Op1wOp16miUiUo7b7Ybb7db9OQ6tlu62y+VCYWFhjd9Pnz4dvXv3xk033QQA\nePXVV/Hdd99hwYIFNRtwONijJ1tyOAC3G7jnHqsrIarJ2+ysNdQ9dezYMQwbNgzZ2dmGFUZU3xjq\nZGfeZqfXY+rfffdd1fM1a9aga9eu3n4UkWU4pk6q8XpMffLkydi3bx8cDgc6dOiAefPmGVkXERF5\nwZDhl1ob4PAL2ZTDAaSlAdHRVldCVJPpwy9EKuDwC6mGoU5EpBCGOvk19tRJNQx18mu33GJ1BUTG\n0nVFKZEv4/l7UhF76kRECmGoExEphKFORKQQhjoRkUIY6kRECmGoExEphKFORKQQhjoRkUIY6kRE\nCmGoExEphKFORKQQhjoRkUIY6kRECmGoExEphKFORKQQhjoRkUIY6kRECtEV6rNnz0bnzp0RHh6O\nyZMnG1WTstxut9Ul2Aa3RTVui2rcFvp5HeqbN2/G2rVrsX//fhw4cAAvvviikXUpiTtsNW6LatwW\n1bgt9PM61OfOnYspU6YgMDAQAHDTTTcZVhQREXnH61DPzc3Fli1b0Lt3bzidTuzatcvIuoiIyAsO\nTbvyPdVdLhcKCwtr/H769OmYOnUq7r33XsyaNQs7d+7EI488gry8vJoNOBzGVkxE5CdqiecrCqjt\njykpKVf829y5c/Hggw8CAHr27IkGDRrgzJkzaNmype6iiIjIO14PvzzwwAPYtGkTAODw4cMoKyur\nEehERGSuWodfalNeXo4xY8Zg3759aNSoEWbOnAmn02lweUREVBde99QDAwORkJCA7Oxs7N69G+fP\nn0dYWBg6deqEGTNmXPY9zz33HDp16oSIiAjs3bvX66LtLjk5udZtsXTpUkRERKBbt2646667sH//\nfguqNMfVtkWlnTt3IiAgAJ988omJ1ZnLk23hdrsRGRmJ8PBwpTtJV9sWp0+fxqBBg9C9e3eEh4dj\n8eLF5hdpgjFjxqB169bo2rXrFV9T59zUDFBRUaF17NhRO3r0qFZWVqZFRERoX3755S9es27dOm3w\n4MGapmlaRkaG1qtXLyOath1PtsX27du14uJiTdM0bcOGDX69LSpf179/f23o0KHaqlWrLKi0/nmy\nLYqKirQuXbpo+fn5mqZp2qlTp6wotd55si1ee+017eWXX9Y0TbZDixYttPLycivKrVdbtmzR9uzZ\no4WHh1/2797kpiHLBGRmZiI0NBTt27dHYGAgRo0ahaSkpF+8Zu3atXjyyScBAL169UJxcTFOnjxp\nRPO24sm26NOnD2644QYAsi0KCgqsKLXeebItALky+eGHH1b6WgdPtsWyZcvw0EMPITg4GADQqlUr\nK0qtd55sizZt2uDcuXMAgHPnzqFly5YICKh1XodP6tevH5o3b37Fv3uTm4aE+okTJxASElL1c3Bw\nME6cOHHV16gYZp5si0stWLAAQ4YMMaM003m6XyQlJeHpp58GoO4UWE+2RW5uLs6ePYv+/fsjKioK\nCQkJZpdpCk+2xbhx43Dw4EG0bdsWERERmDVrltll2oI3uWnI//o8PRC1/zknq+IBXJf/ps2bN2Ph\nwoXYtm1bPVZkHU+2xfPPP4+3334bDocDmqYpOwXWk21RXl6OPXv2YOPGjSgtLUWfPn3Qu3dvdOrU\nyYQKzePJtoiPj0f37t3hdrtx5MgRuFwuZGVloWnTpiZUaC91zU1DQj0oKAj5+flVP+fn51d9hbzS\nawoKChAUFGRE87biybYAgP3792PcuHFITk6u9euXL/NkW+zevRujRo0CICfHNmzYgMDAQAwfPtzU\nWuubJ9siJCQErVq1QuPGjdG4cWNER0cjKytLuVD3ZFts374dU6dOBQB07NgRHTp0QE5ODqKiokyt\n1Wpe5aYRg/3l5eXarbfeqh09elT7+eefr3qiND09XdmTg55si2+++Ubr2LGjlp6eblGV5vBkW1zq\nqaee0lavXm1ihebxZFscOnRIGzBggFZRUaH9+OOPWnh4uHbw4EGLKq4/nmyLF154QYuLi9M0TdMK\nCwu1oKAg7cyZM1aUW++OHj3q0YlST3PTkJ56QEAA5syZg/vuuw8XLlzA2LFj0blzZ8ybNw8AMGHC\nBAwZMgTr169HaGgorrvuOixatMiIpm3Hk23x+uuvo6ioqGocOTAwEJmZmVaWXS882Rb+wpNtERYW\nhkGDBqFbt25o0KABxo0bhy5dulhcufE82RavvPIKRo8ejYiICFy8eBHvvPMOWrRoYXHlxouJiUFa\nWhpOnz6NkJAQTJs2DeXl5QC8z02vLz4iIiL74Z2PiIgUwlAnIlIIQ52IyGCeXP5fKTY2FpGRkYiM\njMTtt9+uezYcx9SJiAy2detWXH/99XjiiSeQnZ3t8fvmzJmDffv2Yf78+V63zZ46EZHBLnf5/5Ej\nRzB48GBERUUhOjoaOTk5Nd63bNkyxMTE6GpbvcUUiIhsaPz48Zg3bx5CQ0OxY8cOTJw4ERs3bqz6\n+zfffINjx47h3nvv1dUOQ52IqJ6VlJQgPT0dI0eOrPpdWVnZL16zYsUKjBw5UvfyKQx1IqJ6dvHi\nRdx44421roeemJiIDz74QHdbHFMnIqpnzZo1Q4cOHbBq1SoAskjXpTfH+eqrr1BUVITevXvrbouh\nTkRksJiYGPTt2xc5OTkICQnBokWLsHTpUixYsKDqbk5r166ten1iYqLuE6SVOKWRiEgh7KkTESmE\noU5EpBCGOhGRQhjqREQKYagTESmEoU5EpJD/B9o2wVREZYt2AAAAAElFTkSuQmCC\n",
       "text": [
        "<matplotlib.figure.Figure at 0x12b7f0690>"
       ]
      }
     ],
     "prompt_number": 99
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "c.nbytes / 1e6"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 100,
       "text": [
        "80.0"
       ]
      }
     ],
     "prompt_number": 100
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%time c.sort()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "CPU times: user 664 ms, sys: 1.61 ms, total: 666 ms\n",
        "Wall time: 665 ms\n"
       ]
      }
     ],
     "prompt_number": 101
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%load_ext cython"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "The cython module is not an IPython extension.\n"
       ]
      }
     ],
     "prompt_number": 102
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# TODO: implement merge of sorted collections"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 103
    }
   ],
   "metadata": {}
  }
 ]
}